Use a static variable to hold the singleton and remove the code that binds
authorEmmanuele Bassi <ebassi@gnome.org>
Tue, 19 Jun 2007 10:29:55 +0000 (10:29 +0000)
committerEmmanuele Bassi <ebassi@src.gnome.org>
Tue, 19 Jun 2007 10:29:55 +0000 (10:29 +0000)
2007-06-19  Emmanuele Bassi  <ebassi@gnome.org>

* gtk/gtkrecentmanager.c: Use a static variable to hold the
singleton and remove the code that binds a recent manager to
a GdkScreen.

(gtk_recent_manager_set_screen): Make it a NOOP.
(gtk_recent_manager_get_for_screen): Proxy for
gtk_recent_manager_get_default().

* gtk/gtk.symbols:
* gtk/gtkrecentmanager.h: Deprecate gtk_recent_manager_set_screen()
and gtk_recent_manager_get_for_screen().

* gtk/gtkmain.c: Force a synchronisation of the GtkRecentManager
singleton (if any) when reaching main loop depth of 0.

* gtk/gtkrecentchooserdefault.c:
(gtk_recent_chooser_default_dispose): Disconnect the changed
signal only if we have a manager and we are connected to it.

(set_recent_manager): Ditto.

* README.in: Document the deprecations.

svn path=/trunk/; revision=18184

ChangeLog
README.in
gtk/gtk.symbols
gtk/gtkmain.c
gtk/gtkrecentchooserdefault.c
gtk/gtkrecentmanager.c
gtk/gtkrecentmanager.h

index 8ff70be2c71faa3e1c9b63964fc9da607bbdcc62..67eab857a08e14a1285e2992ef6cd4bfba799085 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2007-06-19  Emmanuele Bassi  <ebassi@gnome.org>
+
+       * gtk/gtkrecentmanager.c: Use a static variable to hold the
+       singleton and remove the code that binds a recent manager to
+       a GdkScreen.
+
+       (gtk_recent_manager_set_screen): Make it a NOOP.
+       (gtk_recent_manager_get_for_screen): Proxy for
+       gtk_recent_manager_get_default().
+
+       * gtk/gtk.symbols:
+       * gtk/gtkrecentmanager.h: Deprecate gtk_recent_manager_set_screen()
+       and gtk_recent_manager_get_for_screen().
+
+       * gtk/gtkmain.c: Force a synchronisation of the GtkRecentManager
+       singleton (if any) when reaching main loop depth of 0.
+
+       * gtk/gtkrecentchooserdefault.c:
+       (gtk_recent_chooser_default_dispose): Disconnect the changed
+       signal only if we have a manager and we are connected to it.
+
+       (set_recent_manager): Ditto.
+
+       * README.in: Document the deprecations.
+
 2007-06-18  Matthias Clasen <mclasen@redhat.com>
 
        * gtk/gtkcellrendererspin.c: Fix some issues with refcounting
index 800d066ce5789c1a2dc05d50a662d8fffd9431ee..74efdfe2ae74d071c806342f918c45828483e57d 100644 (file)
--- a/README.in
+++ b/README.in
@@ -86,6 +86,12 @@ Release notes for 2.12
   documented as an abstract class, and there is little reason to 
   instantiate it.
   
+* The memory management of the GtkRecentManager object has been changed,
+  as using the screen didn't guarantee that the singleton instance was
+  correctly destroyed. The screen-related functions have been deprecated,
+  and should not be used anymore; the GtkRecentManager instance returned by
+  the gtk_recent_manager_get_default() function is guaranteed to be valid
+  for the entire lifetime of an application.
 
 Release notes for 2.10
 ======================
index 22a9267b77293fca96bce7a01002569c37f26c8e..b06f781efba02c25f1e547c6035fc7dfba031313 100644 (file)
@@ -3203,8 +3203,10 @@ gtk_recent_manager_get_type G_GNUC_CONST
 gtk_recent_manager_new
 gtk_recent_manager_get_items
 gtk_recent_manager_get_default
+#ifndef GTK_DISABLE_DEPRECATED
 gtk_recent_manager_get_for_screen
 gtk_recent_manager_set_screen
+#endif
 gtk_recent_manager_add_item
 gtk_recent_manager_add_full
 gtk_recent_manager_remove_item
index ca9e874bc2f0c886966a7e03bf7268152acbd31f..3da053bcee631b2e3c247c91e2c0db7bd3875682 100644 (file)
@@ -61,6 +61,7 @@
 #include "gtkmain.h"
 #include "gtkmodules.h"
 #include "gtkrc.h"
+#include "gtkrecentmanager.h"
 #include "gtkselection.h"
 #include "gtksettings.h"
 #include "gtkwidget.h"
@@ -1188,9 +1189,14 @@ gtk_main (void)
 
   gtk_main_loop_level--;
 
-  /* Try storing all clipboard data we have */
   if (gtk_main_loop_level == 0)
-    _gtk_clipboard_store_all ();
+    {
+      /* Try storing all clipboard data we have */
+      _gtk_clipboard_store_all ();
+
+      /* Synchronize the recent manager singleton */
+      _gtk_recent_manager_sync ();
+    }
 }
 
 guint
index cf7254b87d1a42034c85c19e19edf0eb8580ba8d..26a44a023479050179c62e3d745516f5d7e18f75 100644 (file)
@@ -601,7 +601,7 @@ gtk_recent_chooser_default_dispose (GObject *object)
       impl->recent_items = NULL;
     }
 
-  if (impl->manager_changed_id)
+  if (impl->manager && impl->manager_changed_id)
     {
       g_signal_handler_disconnect (impl->manager, impl->manager_changed_id);
       impl->manager_changed_id = 0;
@@ -1838,8 +1838,11 @@ set_recent_manager (GtkRecentChooserDefault *impl,
 {
   if (impl->manager)
     {
-      g_signal_handler_disconnect (impl, impl->manager_changed_id);
-      impl->manager_changed_id = 0;
+      if (impl->manager_changed_id)
+        {
+          g_signal_handler_disconnect (impl, impl->manager_changed_id);
+          impl->manager_changed_id = 0;
+        }
 
       impl->manager = NULL;
     }
@@ -1850,9 +1853,11 @@ set_recent_manager (GtkRecentChooserDefault *impl,
     impl->manager = gtk_recent_manager_get_default ();
   
   if (impl->manager)
-    impl->manager_changed_id = g_signal_connect (impl->manager, "changed",
-                                                G_CALLBACK (recent_manager_changed_cb),
-                                                impl);
+    {
+      impl->manager_changed_id = g_signal_connect (impl->manager, "changed",
+                                                   G_CALLBACK (recent_manager_changed_cb),
+                                                   impl);
+    }
 }
 
 GtkWidget *
index 663e5fb4b08943786f7c7bdd821814a49fe22d0b..8c0269947a3db6b8c65a9775cbf1950c9966be5f 100644 (file)
@@ -96,7 +96,6 @@ struct _GtkRecentManagerPrivate
 {
   gchar *filename;
 
-  guint is_screen_singleton : 1;
   guint is_dirty : 1;
   guint write_in_progress : 1;
   guint read_in_progress : 1;
@@ -104,8 +103,6 @@ struct _GtkRecentManagerPrivate
   gint limit;
   gint size;
 
-  GdkScreen *screen;
-  
   GBookmarkFile *recent_items;
   
   time_t last_mtime;
@@ -150,6 +147,8 @@ static void           gtk_recent_info_free            (GtkRecentInfo         *re
 
 static guint signal_changed = 0;
 
+static GtkRecentManager *recent_manager_singleton = NULL;
+
 G_DEFINE_TYPE (GtkRecentManager, gtk_recent_manager, G_TYPE_OBJECT)
 
 static void
@@ -286,13 +285,10 @@ gtk_recent_manager_init (GtkRecentManager *manager)
   priv->limit = DEFAULT_LIMIT;
   priv->size = 0;
   
-  priv->is_screen_singleton = FALSE;
   priv->is_dirty = FALSE;
   priv->write_in_progress = FALSE;
   priv->read_in_progress = FALSE;
 
-  priv->screen = NULL;
-
   priv->filename = g_build_filename (g_get_home_dir (),
                                     GTK_RECENTLY_USED_FILE,
                                     NULL);
@@ -364,7 +360,7 @@ gtk_recent_manager_finalize (GObject *object)
   
   if (priv->recent_items)
     g_bookmark_file_free (priv->recent_items);
-  
+
   /* chain up parent's finalize method */  
   G_OBJECT_CLASS (gtk_recent_manager_parent_class)->finalize (object);
 }
@@ -614,8 +610,7 @@ build_recent_items_list (GtkRecentManager *manager)
  * each time something inside the list changes.
  *
  * #GtkRecentManager objects are expensive: be sure to create them only when
- * needed. You should use the gtk_recent_manager_new_for_screen() or the
- * gtk_recent_manager_get_default() functions instead.
+ * needed. You should use gtk_recent_manager_get_default() instead.
  *
  * Return value: A newly created #GtkRecentManager object.
  *
@@ -630,20 +625,21 @@ gtk_recent_manager_new (void)
 /**
  * gtk_recent_manager_get_default:
  *
- * Gets the recent manager for the default screen. See
- * gtk_recent_manager_get_for_screen().
+ * Gets a unique instance of #GtkRecentManager, that you can share
+ * in your application without caring about memory management. The
+ * returned instance will be freed when you application terminates.
  *
- * Return value: A unique #GtkRecentManager associated with the
- *   default screen. This recent manager is associated with the
- *   screen and can be used as long as the screen is open.
- *   Do not ref or unref it.
+ * Return value: A unique #GtkRecentManager. Do not ref or unref it.
  *
  * Since: 2.10
  */
 GtkRecentManager *
 gtk_recent_manager_get_default (void)
 {
-  return gtk_recent_manager_get_for_screen (gdk_screen_get_default ());
+  if (G_UNLIKELY (!recent_manager_singleton))
+    recent_manager_singleton = gtk_recent_manager_new ();
+
+  return recent_manager_singleton;
 }
 
 /**
@@ -664,70 +660,16 @@ gtk_recent_manager_get_default (void)
  *   and can be used as long as the screen is open. Do not ref or
  *   unref it.
  *
+ * @Deprecated: 2.12: This function has been deprecated and should
+ *   not be used in newly written code. Calling this function is
+ *   equivalent to calling gtk_recent_manager_get_default().
+ *
  * Since: 2.10
  */
 GtkRecentManager *
 gtk_recent_manager_get_for_screen (GdkScreen *screen)
 {
-  GtkRecentManager *manager;
-
-  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-  g_return_val_if_fail (!screen->closed, NULL);
-
-  manager = g_object_get_data (G_OBJECT (screen), "gtk-recent-manager-default");
-  if (!manager)
-    {
-      GtkRecentManagerPrivate *priv;
-      
-      manager = gtk_recent_manager_new ();
-      gtk_recent_manager_set_screen (manager, screen);
-
-      priv = manager->priv;
-      priv->is_screen_singleton = TRUE;
-
-      g_object_set_data (G_OBJECT (screen), I_("gtk-recent-manager-default"), manager);
-    }
-
-  return manager;
-}
-
-static void
-display_closed (GdkDisplay       *display,
-               gboolean          is_error,
-               GtkRecentManager *manager)
-{
-  GtkRecentManagerPrivate *priv = manager->priv;
-  GdkScreen *screen = priv->screen;
-  gboolean was_screen_singleton = priv->is_screen_singleton;
-
-  if (was_screen_singleton)
-    {
-      g_object_set_data (G_OBJECT (screen), I_("gtk-recent-manager-default"), NULL);
-      priv->is_screen_singleton = FALSE;
-    }
-
-  gtk_recent_manager_set_screen (manager, NULL);
-
-  if (was_screen_singleton)
-    g_object_unref (manager);
-}
-
-static void
-unset_screen (GtkRecentManager *manager)
-{
-  GtkRecentManagerPrivate *priv = manager->priv;
-  GdkDisplay *display;
-
-  if (priv->screen)
-    {
-      display = gdk_screen_get_display (priv->screen);
-
-      g_signal_handlers_disconnect_by_func (display,
-                                           (gpointer) display_closed,
-                                           manager);
-
-      priv->screen = NULL;
-    }
+  return gtk_recent_manager_get_default ();
 }
 
 /**
@@ -740,30 +682,16 @@ unset_screen (GtkRecentManager *manager)
  * storage.
  * 
  * Since: 2.10
+ *
+ * @Deprecated: 2.12: This function has been deprecated and should
+ *   not be used in newly written code. Calling this function has
+ *   no effect.
  */
 void
 gtk_recent_manager_set_screen (GtkRecentManager *manager,
                               GdkScreen        *screen)
 {
-  GtkRecentManagerPrivate *priv;
-  GdkDisplay *display;
-
-  g_return_if_fail (GTK_IS_RECENT_MANAGER (manager));
-  g_return_if_fail (screen == NULL || GDK_IS_SCREEN (screen));
-
-  priv = manager->priv;
 
-  unset_screen (manager);
-
-  if (screen)
-    {
-      display = gdk_screen_get_display (screen);
-
-      priv->screen = screen;
-
-      g_signal_connect (display, "closed",
-                       G_CALLBACK (display_closed), manager);
-    }
 }
 
 /**
@@ -2448,5 +2376,21 @@ gtk_recent_info_has_group (GtkRecentInfo *info,
   return FALSE;
 }
 
+/*
+ * _gtk_recent_manager_sync:
+ * 
+ * Private function for synchronising the recent manager singleton.
+ */
+void
+_gtk_recent_manager_sync (void)
+{
+  if (recent_manager_singleton)
+    {
+      /* force a dump of the contents of the recent manager singleton */
+      recent_manager_singleton->priv->is_dirty = TRUE;
+      gtk_recent_manager_real_changed (recent_manager_singleton);
+    }
+}
+
 #define __GTK_RECENT_MANAGER_C__
 #include "gtkaliasdef.c"
index 37e7121a623d65d28f9a95ec1f7ce1f2283d0043..b184b3fa817d476e60cbcbc35c3edda2e2eb6267 100644 (file)
@@ -136,10 +136,12 @@ GType               gtk_recent_manager_get_type       (void) G_GNUC_CONST;
 
 GtkRecentManager *gtk_recent_manager_new            (void);
 GtkRecentManager *gtk_recent_manager_get_default    (void);
-GtkRecentManager *gtk_recent_manager_get_for_screen (GdkScreen            *screen);
 
+#ifndef GTK_DISABLE_DEPRECATED
+GtkRecentManager *gtk_recent_manager_get_for_screen (GdkScreen            *screen);
 void              gtk_recent_manager_set_screen     (GtkRecentManager     *manager,
                                                     GdkScreen            *screen);
+#endif
 
 gboolean          gtk_recent_manager_add_item       (GtkRecentManager     *manager,
                                                     const gchar          *uri);
@@ -203,6 +205,9 @@ gboolean              gtk_recent_info_exists               (GtkRecentInfo  *info
 gboolean              gtk_recent_info_match                (GtkRecentInfo  *info_a,
                                                            GtkRecentInfo  *info_b);
 
+/* private */
+void _gtk_recent_manager_sync (void);
+
 G_END_DECLS
 
 #endif /* __GTK_RECENT_MANAGER_H__ */